// wip work in progress当前正在工作中的

import {
  updateFragmentComponent,
  updateFunctionComponent,
  updateHostComponent,
} from "./ReactFiberReconciler";
import { scheduleCallback, shouldYield } from "./scheduler";
import { isFn, isStr, Placement, Update, updateNode } from "./utils";

let wipRoot = null;
// 下一个fiber节点
let nextUnitOfwork = null;
export function scheduleUpdateOnFiber(fiber) {
  fiber.alternate = { ...fiber };
  wipRoot = fiber;
  nextUnitOfwork = fiber;
  scheduleCallback(workLoop);
}

function performUnitOfWork(wip) {
  // 1. 更新wip
  const { type } = wip;
  if (isStr(type)) {
    updateHostComponent(wip);
  } else if (isFn(type)) {
    updateFunctionComponent(wip);
  } else {
    updateFragmentComponent(wip);
  }
  // todo
  // 2. 返回下一个要更新的任务 深度优先遍历
  if (wip.child) {
    return wip.child;
  }
  let next = wip;

  while (next) {
    if (next.sibling) {
      return next.sibling;
    }
    next = next.return;
  }
  return null;
}

function workLoop() {
  while (nextUnitOfwork && !shouldYield()) {
    nextUnitOfwork = performUnitOfWork(nextUnitOfwork);
  }

  if (!nextUnitOfwork && wipRoot) {
    commitRoot();
  }
}

// requestIdleCallback(workLoop);

function commitRoot() {
  isFn(wipRoot.type) ? commitWorker(wipRoot) : commitWorker(wipRoot.child);
  wipRoot = null;
}

function commitWorker(wip) {
  if (!wip) return;

  // 1。提交自己
  const { flags, stateNode } = wip;
  // fiber可能没有dom节点，比如函数组件类组件
  let parentNode = getParentNode(wip.return); //wip.return.stateNode; // 父dom节点
  if (flags & Placement && stateNode) {
    parentNode.appendChild(stateNode);
  }
  if (flags & Update && stateNode) {
    updateNode(stateNode, wip.alternate.props, wip.props);
  }
  // 2、 子节点
  commitWorker(wip.child);
  // 3.兄弟
  commitWorker(wip.sibling);
}

function getParentNode(fiber) {
  while (fiber) {
    if (fiber.stateNode) {
      return fiber.stateNode;
    }
    fiber = fiber.return;
  }
}
